/*!
 *****************************************************************************
 *
 *  Copyright © 2017-2018 none. All Rights Reserved.
 *
 * \file      main.c
 * \author    HansenLiu
 * \version   1.0
 * \date      2021年9月8日
 * \brief     main函数
 *
 *----------------------------------------------------------------------------
 * \attention
 *
 *
 *****************************************************************************
 */

/*****************************************************************************
 change history: 
    1.date  : 2021年9月8日
      author: HansenLiu
      change: create file
      
change history: 
   2.date  : 2021年10月2日
	 author: HansenLiu
	 change: 添加帧控制的模块

*****************************************************************************/

/*----------------------------------------------*
 * 包含头文件                                        *
 *----------------------------------------------*/

#include "multiClient.h"
#include "FRAME_Control.h"
#include "Bridge_FRAME_Control.h"




/*----------------------------------------------*
 * enum                                     *
 *----------------------------------------------*/
enum
{
    CLIENT_0,
    CLIENT_1,
    CLIENT_2,
};


/*----------------------------------------------*
 * define                                    *
 *----------------------------------------------*/

#define 	heartSendPeriod 		100





/*----------------------------------------------*
 * 内部函数                                     *
 *----------------------------------------------*/





static uint16_t  AgetRecv0(uint8_t *buf ,  uint16_t len);
static uint16_t  AgetRecv1(uint8_t *buf ,  uint16_t len);
static uint16_t  AgetRecv2(uint8_t *buf ,  uint16_t len);



static uint8_t numClint = 0;	//客户端的实际数量


static uint32_t sProt1msTick;	//1ms计时器累计


static TcpClient CliientAget[MAXCLIENT]= //客户端定义实例化
{

	/*	add your code here*/

    {
        AgetRecv0,
        0,
        "192.168.177.1",
        601,
        0,
        CLIENT_0
    },
    {
        AgetRecv1,
        0,
        "192.168.177.1",
        602,

        0,
        CLIENT_1
    },
    {
        AgetRecv2,
        0,
        "192.168.177.1",
        603,

        0,
        CLIENT_2
    },
};



/*****************************************************************************
 函 数 名  : AgetRecv0
 功能描述  : 接收回调
 输入参数  : uint8_t *buf  
             uint8_t len   
 输出参数  : 无
 返 回 值  : 
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2021年9月21日
    作    者   : HansenLiu
    修改内容   : 新生成函数

*****************************************************************************/
static uint16_t  AgetRecv0(uint8_t *buf ,  uint16_t len)
{
    uint16_t i = 0;

    if(len < 1)
	{
		return i;
	}
	
    Debug("AgetRecv0 recv: ");

/*  add your code here*/

#if 1
    if(len > 0)
    {
        for(i = 0; i < len; i++)
        {
            printf("%x ",buf[i]);
        }
    }
#endif

    printf("\n");

	return i;
}

/*****************************************************************************
 函 数 名  : AgetRecv0
 功能描述  : 接收回调
 输入参数  : uint8_t *buf  
             uint8_t len   
 输出参数  : 无
 返 回 值  : 
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2021年9月21日
    作    者   : HansenLiu
    修改内容   : 新生成函数

*****************************************************************************/
static uint16_t  AgetRecv1(uint8_t *buf ,  uint16_t len)
{
    uint16_t i;
    
    if(len <= 0)
	{
		return;
	}
	
    Debug("AgetRecv1 recv: ");

    if(len > 0)
    {
        for(i = 0; i < len; i++)
        {
            printf("%x ",buf[i]);
        }
    }

    printf("\n");

	return i;
}

/*****************************************************************************
 函 数 名  : AgetRecv0
 功能描述  : 接收回调
 输入参数  : uint8_t *buf  
             uint8_t len   
 输出参数  : 无
 返 回 值  : 
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2021年9月21日
    作    者   : HansenLiu
    修改内容   : 新生成函数

*****************************************************************************/
static uint16_t  AgetRecv2(uint8_t *buf ,  uint16_t len)
{
    uint16_t i = 0;

	if(len <= 0)
	{
		return;
	}
	
    Debug("AgetRecv2 recv: ");

    if(len > 0)
    {
        for(i = 0; i < len; i++)
        {
            printf("%x ",buf[i]);
        }
    }

    printf("\n");

	return i;
}

//帧控制需要根据命令来索引不同的数据包
uint16_t  sMsgCommand[] = {

	0x00,
	0x01,
};


/*****************************************************************************
 Prototype    : get_timetick
 Description  : 返回当前Linux的时间，单位 1ms / 10 
 Input        : None
 Output       : None
 Return Value : static
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2021/10/2
    Author       : Hansen Liu
    Modification : Created function

*****************************************************************************/
static unsigned long SystemTick10msCount()
{
	struct timespec ts;
	
	clock_gettime(CLOCK_MONOTONIC, &ts);	//makefile 里添加 -lrt 
	
	return (ts.tv_sec * 1000 + ts.tv_nsec/1000000) / 10;
}

/*****************************************************************************
 Prototype    : Timer100ms
 Description  : 100ms计时回调
 Input        : void  
 Output       : None
 Return Value : static
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2021/10/2
    Author       : Hansen Liu
    Modification : Created function

*****************************************************************************/
static void Timer100ms(void)
{
	sProt1msTick = SystemTick10msCount() * 10;	// 1ms计数值
	
	static uint32_t sTime = 0;
	if((sProt1msTick - sTime  > 100))		//100ms触发
	{
		Pro_FRAME_Ctrl100msCallBack();

		sTime = sProt1msTick;

		//Debug("sTime = %d", sTime);
	}
	
}

/*****************************************************************************
 Prototype    : FrameConrolInit
 Description  : 用来赋值给帧控制模块的初始化
 Input        : void  
 Output       : None
 Return Value : 
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2021/10/2
    Author       : Hansen Liu
    Modification : Created function

*****************************************************************************/
void FrameConrolInit(void)
{
	tcp_client_init(0);
    tcp_client_create(CliientAget[0]);
}

/*****************************************************************************
 Prototype    : FrameControlSend
 Description  : 帧发送的数量链路层
 Input        : const uint8_t *buf  
                uint16_t len        
 Output       : None
 Return Value : 
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2021/10/2
    Author       : Hansen Liu
    Modification : Created function

*****************************************************************************/
void FrameControlSend(const uint8_t *buf, uint16_t len)
{

	tcp_client_Send(0, buf, len);

}

/*****************************************************************************
 Prototype    : FrameControlRecv
 Description  : 帧发送的数据链路层
 Input        : uint8_t *buf     
                uint16_t bufLen  
 Output       : None
 Return Value : 
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2021/10/2
    Author       : Hansen Liu
    Modification : Created function

*****************************************************************************/
uint16_t FrameControlRecv(uint8_t *buf, uint16_t bufLen)
{
	CliientAget[0].Recv(buf, bufLen);

	tcp_client_Recv(0, buf, bufLen);
}


/*****************************************************************************
 Prototype    : Fill0x01
 Description  : 消息体的内容填充函数
 Input        : uint16_t msg  
                uint8_t *buf  
 Output       : None
 Return Value : static
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2021/10/2
    Author       : Hansen Liu
    Modification : Created function

*****************************************************************************/
static uint16_t Fill0x01(uint16_t msg, uint8_t *buf)
{
	uint16_t index = 0;

	uint8_t head[] = {0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9 , 0xFF};

	memcpy(buf, head, sizeof(head));
	index += sizeof(head);

	Debug("Fill0x01 ----  success ");
	return index;
}


/*****************************************************************************
 Prototype    : FrameRecvDeal
 Description  : 帧控制需要的接收处理函数
 Input        : uint8_t *pRecv    
                uint16_t recvLen  
 Output       : None
 Return Value : 
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2021/10/3
    Author       : Hansen Liu
    Modification : Created function

*****************************************************************************/
GPRS_FRAME_RECV_RT FrameRecvDeal(uint8_t *pRecv, uint16_t recvLen)
{

	GPRS_FRAME_RECV_RT rt;

	CliientAget[0].Recv(pRecv, recvLen);
	
	return rt;
}


/*****************************************************************************
 Prototype    : GPRS_FrameInit
 Description  : GPRS的帧控制 初始化
 Input        : void  
 Output       : None
 Return Value : 
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2021/11/12
    Author       : Hansen Liu
    Modification : Created function

*****************************************************************************/
void GPRS_FrameInit(void)
{

	//一个帧控制模块目前只能支持一个客户端的发送和接收
	GPRS_FRAME_INT_CTRL initCtrl = {0};
	initCtrl.init = FrameConrolInit;
	initCtrl.send = FrameControlSend;
	initCtrl.recv = FrameControlRecv;
	//initCtrl.recv = NULL;	//不能为NULL，不然会段错误

	GPRS_FRAME_APP_CTRL appInitData;
	memset(&appInitData, 0, sizeof(GPRS_FRAME_APP_CTRL));
	
	appInitData.sendInt = 2;
	
	// 需要所以命令的数组
	appInitData.pMsgBuf = sMsgCommand;
	appInitData.msgNum = sizeof(sMsgCommand);
	
	//appInitData.recvDeal = NULL;
	//appInitData.recvDeal = FrameRecvDeal;
	

	GPRS_FRAME_AppInit(initCtrl, &appInitData);
	//Timer100ms();		//必须需要开启及时才能使用


}

/*****************************************************************************
 Prototype    : BRG_FrameInit
 Description  : BRG帧控制模块的初始化
 Input        : void  
 Output       : None
 Return Value : 
 Calls        : 
 Called By    : 
 
  History        :
  1.Date         : 2021/11/12
    Author       : Hansen Liu
    Modification : Created function

*****************************************************************************/
void BRG_FrameInit(void)
{

	//一个帧控制模块目前只能支持一个客户端的发送和接收
	BRIDGE_FRAME_INT_CTRL initCtrl = {0};
	initCtrl.init = FrameConrolInit;
	initCtrl.send = FrameControlSend;
	initCtrl.recv = FrameControlRecv;


	BRIDGE_FRAME_APP_CTRL appInitData =
	{
		.sendInt = 0,
		//.recvDeal = FrameRecvDeal,

		// 不需要知道命令的数组了，但是使用过程中需要生成命令
		//uint32_t msg = BRIDGE_MSG_COMPOSE(0, 0, sMsgCommand[0]);
		//BRIDGE_FRAME_CtrlSendStart(msg, period, 0, 0, Fill0x01, 0);

		
	};


	BRIDGE_FRAME_AppInit(&initCtrl, &appInitData);


	
}


/*****************************************************************************
 函 数 名  : main
 功能描述  : 主循环
 输入参数  : int argc      
             char *argv[]  
 输出参数  : 无
 返 回 值  : 
 调用函数  : 
 被调函数  : 
 
 修改历史      :
  1.日    期   : 2021年9月21日
    作    者   : HansenLiu
    修改内容   : 新生成函数

*****************************************************************************/
int main(int argc, char *argv[])
{

	//init_sigaction();
	//while(1);
    uint8_t idx = 1;
    uint8_t msg[10]= {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 , 0x0F};	
	uint16_t period = 10;

	uint32_t msg1 = BRIDGE_MSG_COMPOSE(0, 0, sMsgCommand[0]);
	BRIDGE_FRAME_CtrlSendStart(msg, period, 0, 0, Fill0x01, 0);

	
	GPRS_FRAME_CtrlSendStart(sMsgCommand[0], period, 0, 0, Fill0x01, 0);
	//GPRS_FRAME_CtrlSendNow(sMsgCommand[0], 0);
	
#if 1	


    //tcp_client_init();
    //tcp_client_create(CliientAget[numClint++]);
    //tcp_client_create(CliientAget[numClint++]);
    //tcp_client_create(CliientAget[numClint++]);

    while(1)
    {	

        msg[9] = 0xF0 + idx + 1;
		
        if(idx >= numClint )//MAXCLIENT
        {
            idx = 0;
        }
        //tcp_client_Send(idx, msg, 10);
		
        idx++;

		//这两个函数必须加到主循环中
		Timer100ms();
		
		GPRS_FRAME_Main();
		//GPRS_FRAME_CtrlSendStart(sMsgCommand[0], period, 0, 0, Fill0x01, 0);
		//GPRS_FRAME_CtrlSendNow(sMsgCommand[0], 0);

		BRIDGE_FRAME_Main();
		
		
        usleep(100 * 1000);
    }

	
#endif


    return (0);
}








